package com.beg.cant.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.toolkit.StringUtils;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.beg.cant.dto.PageRequest;
import com.beg.cant.dto.PageResponse;
import com.beg.cant.dto.WithdrawDTO;
import com.beg.cant.dto.WithdrawQueryRequest;
import com.beg.cant.entity.User;
import com.beg.cant.entity.Withdraw;
import com.beg.cant.mapper.UserMapper;
import com.beg.cant.mapper.WithdrawMapper;
import com.beg.cant.service.WithdrawService;
import com.beg.cant.vo.WithdrawStatisticsVO;
import com.beg.cant.vo.WithdrawVO;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;

import java.io.UnsupportedEncodingException;
import java.math.BigDecimal;
import java.net.URLDecoder;
import java.nio.charset.StandardCharsets;
import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Objects;
import java.util.stream.Collectors;

@Slf4j
@Service
@RequiredArgsConstructor
public class WithdrawServiceImpl extends ServiceImpl<WithdrawMapper, Withdraw> implements WithdrawService {
    private final WithdrawMapper withdrawMapper;
    private final UserMapper userMapper;

    @Override
    public PageResponse<WithdrawVO> getWithdrawList(PageRequest request) {
        // 构建查询条件
        LambdaQueryWrapper<Withdraw> queryWrapper = new LambdaQueryWrapper<>();
        if (request.getState() != null) {
            queryWrapper.eq(Withdraw::getStatus, request.getState());
        }
        if (request.getCode() != null) {
            queryWrapper.eq(Withdraw::getUserId, request.getCode());
        }
        if (request.getStartTime()!=null){
            queryWrapper.ge(Withdraw::getCreateAt,request.getStartTime());
        }
        if (request.getEndTime()!=null){
            queryWrapper.le(Withdraw::getCreateAt,request.getEndTime());
        }
        queryWrapper.orderByAsc(Withdraw::getAmount).orderByDesc(Withdraw::getCreateAt);

        // 创建分页对象
        Page<Withdraw> page = new Page<>(request.getPageNum(), request.getPageSize());
        
        // 执行分页查询
        IPage<Withdraw> withdrawPage = withdrawMapper.selectPage(page, queryWrapper);
        
        // 转换为VO对象
        List<WithdrawVO> withdrawVOList = withdrawPage.getRecords().stream()
                .map(withdraw -> {
                    WithdrawVO vo = new WithdrawVO();
                    BeanUtils.copyProperties(withdraw, vo);
                    User user = userMapper.selectById(withdraw.getUserId());
                    if (user != null) {
                        vo.setOpenid(user.getOpenid());
                    }
                    return vo;
                })
                .collect(Collectors.toList());
        
        // 构建分页响应
        return PageResponse.of(withdrawVOList, withdrawPage.getTotal(), request);
    }

    @Override
    public List<Withdraw> getUserById(Long id) {
        try {
            LambdaQueryWrapper<Withdraw> wrapper = new LambdaQueryWrapper<>();
            wrapper.eq(Withdraw::getUserId,id).orderByAsc(Withdraw::getCreateAt);
            List<Withdraw> withdraws = withdrawMapper.selectList(wrapper);
            return withdraws;
        }catch (NoClassDefFoundError e){
            System.out.println(e);
            throw new RuntimeException(getEntityClass().getName());
        }
    }

    @Override
    public void setWithdraw(WithdrawDTO withdrawDTO){
        LambdaQueryWrapper<User> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(User::getId,withdrawDTO.getUserId());
        List<User> users = userMapper.selectList(wrapper);
        if (users.get(0).getTotal().compareTo(withdrawDTO.getAmount().doubleValue())<0) {
            throw new RuntimeException("余额不足");
        }
        withdrawMapper.insert(Withdraw.builder()
                .amount(withdrawDTO.getAmount())
                .status(0).userId(withdrawDTO
                        .getUserId()).build());
        userMapper.updateById(User.builder()
                        .id(withdrawDTO.getUserId())
                        .total(users.get(0).getTotal()-withdrawDTO.getAmount().doubleValue())
                .build());
    }

    @Override
    public void updateWithdraw(String code) {
        LambdaUpdateWrapper<Withdraw> wrapper = new LambdaUpdateWrapper<>();
        wrapper.set(Withdraw::getStatus,2).eq(Withdraw::getOutBillNo,code);
        withdrawMapper.update(wrapper);
    }

    @Override
    public void finishWithdraw(String code) throws UnsupportedEncodingException {
        // 解码URL编码的字符串
        String decodedCode = URLDecoder.decode(code.replace("code=", ""), StandardCharsets.UTF_8.toString());
        log.info("审核通过提现{}", decodedCode);

        // 将解码后的字符串转为整数列表
        List<Integer> codesList = Arrays.stream(decodedCode.split(","))
                .map(Integer::parseInt)
                .collect(Collectors.toList());
        LambdaUpdateWrapper<Withdraw> wr = new LambdaUpdateWrapper<>();
        log.info("这个code{}",codesList);
        wr.in(Withdraw::getId, codesList).set(Withdraw::getStatus,1);
        withdrawMapper.update(wr);
    }

    @Override
    public WithdrawVO selectWithdraw(String code) {
        Withdraw withdraw = withdrawMapper.selectById(code);
        WithdrawVO withdrawVO = new WithdrawVO();
        BeanUtils.copyProperties(withdraw,withdrawVO);
        withdrawVO.setOpenid(userMapper.selectById(withdraw.getUserId()).getOpenid());
        return withdrawVO;
    }

    @Override
    public void upWithdraw(Long id, String code) {
        withdrawMapper.updateById(Withdraw.builder()
                        .id(id)
                        .outBillNo(code)
                .build());
    }

    @Override
    public WithdrawStatisticsVO getWithdrawStatistics() {
        LocalDateTime now = LocalDateTime.now();
        LocalDateTime startOfToday = now.toLocalDate().atStartOfDay();
        LocalDateTime startOfMonth = now.withDayOfMonth(1).toLocalDate().atStartOfDay();
        ArrayList<Integer> list = new ArrayList<>();
        list.add(1);
        list.add(2);
        // 今日提现总额
        LambdaQueryWrapper<Withdraw> todayWrapper = new LambdaQueryWrapper<>();
        todayWrapper.ge(Withdraw::getCreateAt, startOfToday)
                   .le(Withdraw::getCreateAt, now)
                   .in(Withdraw::getStatus, list);
        Double todayAmount = list(todayWrapper).stream()
                .mapToDouble(Withdraw::getAmount)
                .sum();
        
        // 待审核金额
        LambdaQueryWrapper<Withdraw> pendingWrapper = new LambdaQueryWrapper<>();
        pendingWrapper.eq(Withdraw::getStatus, 0);
        Double pendingAmount = list(pendingWrapper).stream()
                .mapToDouble(Withdraw::getAmount)
                .sum();
        
        // 本月提现总额
        LambdaQueryWrapper<Withdraw> monthWrapper = new LambdaQueryWrapper<>();
        monthWrapper.ge(Withdraw::getCreateAt, startOfMonth)
                   .le(Withdraw::getCreateAt, now)
                   .in(Withdraw::getStatus, list);
        Double monthAmount = list(monthWrapper).stream()
                .mapToDouble(Withdraw::getAmount)
                .sum();
        
        // 累计提现总额
        LambdaQueryWrapper<Withdraw> totalWrapper = new LambdaQueryWrapper<>();
        totalWrapper.eq(Withdraw::getStatus, list);
        Double totalAmount = list(totalWrapper).stream()
                .mapToDouble(Withdraw::getAmount)
                .sum();
        
        return WithdrawStatisticsVO.builder()
                .todayAmount(todayAmount)
                .pendingAmount(pendingAmount)
                .monthAmount(monthAmount)
                .totalAmount(totalAmount)
                .build();
    }
}
